/**
 * Copyright 2022 Stars embedded, All Rights Reserved.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * @FilePath: /FA/SmartCentControl/entry/src/main/js/default/pages/index/index.js
 * @Description:
 * @Author: lin zhang
 * @Date: 2022-03-04 18:55:47
 * @LastEditTime: 2022-03-15 15:35:18
 * @LastEditors: lin zhang
 * 变更历史:
 */

#include "device_resource_if.h"
#include "hdf_device_desc.h"
#include "hdf_log.h"
#include "los_printf.h"
#include "hdf_log.h"
#include <stdio.h>
#include <stdint.h>
#include "los_task.h"
#include "los_mux.h"
#include "los_swtmr.h"
#include "mqttclient.h"
static mqtt_client_t *client = NULL;
UINT32 g_taskMux;
UINT32 g_taskMQTTID; 
UINT32 Flag = 0;
UINT16 id1; // timer id1
int32_t count = 0;
static int mqtt_publish_handle1(void)
{
    PRINTK("Enter mqtt_publish_handle1");
    mqtt_message_t msg;
    memset(&msg, 0, sizeof(msg));
    while (1)
    {
        LOS_TaskDelay(6 * 1000);
        msg.qos = 0;
        msg.payload = (void *) "";
        mqtt_publish(client, "$oc/devices/61ed6998de9933029be43a78_micro/sys/messages/up", &msg);
        
    }
    return 0;
}

static void Handler(void* client, message_data_t* msg)
{
    (void) client;
    PRINTK("-----------------------------------------------------------------------------------");
    PRINTK("%s:%d %s()...\ntopic: %s\nmessage:%s", __FILE__, __LINE__, __FUNCTION__, msg->topic_name, (char*)msg->message->payload);
    PRINTK("-----------------------------------------------------------------------------------");
}

static int32_t Scp_Init_Mqtt()
{

    mqtt_log_init();

    client = mqtt_lease();

    mqtt_set_host(client, "121.36.42.100");
    mqtt_set_port(client, "1883");
    mqtt_set_user_name(client, "61ed6998de9933029be43a78_micro");
    mqtt_set_password(client, "846f432406041be94ece4dd4eca94119d22310208b61407c2c93b2abbbfe699b");
    mqtt_set_client_id(client, "61ed6998de9933029be43a78_micro_0_0_2022030604");
    mqtt_set_clean_session(client, 1);

    mqtt_connect(client);
    mqtt_subscribe(client, "$oc/devices/61ed6998de9933029be43a78_micro/sys/commands/#", QOS0, Handler);
    return HDF_SUCCESS;
}

static int32_t Scp_Publish_Mqtt()
{
    mqtt_publish_handle1();
    return HDF_SUCCESS;
}



static int32_t Scp_Publish_Command(struct HdfSBuf *data)
{
    mqtt_message_t msg;
    memset(&msg, 0, sizeof(msg));
    const char * str = HdfSbufReadString(data);
    PRINTK("%s",str);
    msg.payload = (void *)str;
    mqtt_publish(client, "$oc/devices/{device_id}/sys/properties/report", &msg);
    return HDF_SUCCESS;
}
#include "gpio_if.h"
#include "osal_irq.h"
#include "osal_time.h"

void Voice_Publish(int32_t cmdType)
{
    mqtt_message_t msg;
    memset(&msg, 0, sizeof(msg));
    switch (cmdType)
    {
        case 5:
            
            msg.payload = (void *)"{\"services\":[{\"service_id\":\"smartctn\",\"properties\":{\"led\":0,\"temp\":30,\"humi\":70,\"mode\":\"OFF\"}}]}";
            mqtt_publish(client, "$oc/devices/{device_id}/sys/properties/report", &msg);
        case 6:
            msg.payload = (void *)"{\"services\":[{\"service_id\":\"smartctn\",\"properties\":{\"led\":1,\"temp\":30,\"humi\":70,\"mode\":\"OFF\"}}]}";
            mqtt_publish(client, "$oc/devices/{device_id}/sys/properties/report", &msg);
        break;
    
    default:
        break;
    }
}

void Timer1_Callback(UINT32 arg) // 回调函数1 
{
   if(Flag != 0)
   {
        LOS_SwtmrStop(id1);
        Voice_Publish(count);
        count = 0;
        Flag = 0;
   }
}  

/* 中断服务函数*/
static int32_t TestCaseGpioIrqHandler(uint16_t gpio, void *data)
{
    if(Flag == 0)
    {
        Flag = 1;
        LOS_SwtmrStart(id1);
    }
    else{
        count ++;
    }
   /* mqtt_message_t msg;
    memset(&msg, 0, sizeof(msg));
    msg.payload = (void *)"{\"services\":[{\"service_id\":\"smartctn\",\"properties\":{\"led\":1,\"temp\":30,\"humi\":70,\"mode\":\"OFF\"}}]}";
    mqtt_publish(client, "$oc/devices/{device_id}/sys/properties/report", &msg);
*/
    return HDF_SUCCESS;
}

static int32_t Init_Voice_Model()
{
    int32_t ret;
    uint16_t mode;
    uint16_t gpio = 16; /* 待测试的GPIO管脚号 */
   
    /* 将管脚方向设置为输出 */
    ret = GpioSetDir(gpio, GPIO_DIR_IN);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: set dir fail! ret:%d\n", __func__, ret);
        return ret;
    }

    /* 先禁止该管脚中断 */
    ret = GpioDisableIrq(gpio);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: disable irq fail! ret:%d\n", __func__, ret);
        return ret;
    }

    /* 为管脚设置中断服务函数，触发模式为上升沿和下降沿共同触发 */
    mode = OSAL_IRQF_TRIGGER_RISING;
    HDF_LOGE("%s: mode:%0x\n", __func__, mode);
    ret = GpioSetIrq(gpio, mode, TestCaseGpioIrqHandler, NULL);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: set irq fail! ret:%d\n", __func__, ret);
        return ret;
    }

    /* 使能此管脚中断 */
    ret = GpioEnableIrq(gpio);
    if (ret != HDF_SUCCESS) {
        HDF_LOGE("%s: enable irq fail! ret:%d\n", __func__, ret);
        (void)GpioUnSetIrq(gpio);
        return ret;
    }
    LOS_SwtmrCreate(500, LOS_SWTMR_MODE_PERIOD, Timer1_Callback, &id1, 1);
    return HDF_SUCCESS;
}

int32_t ScpDriverDispatch(struct HdfDeviceIoClient *client, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
{

    PRINTK("Enter ScpDriverDispatch\n");
    if (!HdfSbufWriteInt32(reply, 10))
    {
        HDF_LOGE("replay is fail");
        return HDF_FAILURE;
    }
    if(cmdCode == 0)
    {
        Scp_Init_Mqtt();
        Init_Voice_Model();
    }
    if(cmdCode == 1)
    {
        Scp_Publish_Mqtt();
    }
    if(cmdCode == 2)
    {
        Scp_Publish_Command(data);
    }
    return HDF_SUCCESS;
}

/* HdfDriverEntry hook function implementations */
static int32_t ScpDriverBind(struct HdfDeviceObject *device)
{
    if (device == NULL)
    {
        HDF_LOGE("Scp driver bind failed!");
        return HDF_ERR_INVALID_OBJECT;
    }
    static struct IDeviceIoService scpDriver = {
        .Dispatch = ScpDriverDispatch,
    };
    device->service = (struct IDeviceIoService *)(&scpDriver);
    return HDF_SUCCESS;
}

static int32_t ScpDriverInit(struct HdfDeviceObject *device)
{
    return HDF_SUCCESS;
}

static void ScpDriverRelease(struct HdfDeviceObject *device)
{
}

/* HdfDriverEntry definition */
struct HdfDriverEntry g_ScpDriverEntry = {
    .moduleVersion = 1,
    .moduleName = "HDF_PERIPHERAL_SCP",
    .Bind = ScpDriverBind,
    .Init = ScpDriverInit,
    .Release = ScpDriverRelease,
};

/* Init HdfDriverEntry */
HDF_INIT(g_ScpDriverEntry);